home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2000 Spring
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin
/
F2JW
/
trans
/
prep.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-08-22
|
15KB
|
568 lines
//
// フランス語 → 日本語 翻訳プログラム
//
// 前置詞の処理
#include "stdafx.h"
#include <string.h>
#include <ctype.h>
#include "f2j.h"
#include "score.h"
#include "myprot.h"
//
// 前置詞 + 前置詞 -> 前置詞
// eg) comme si, tandis que, ...
//
void
CombinePrepositions( TOKEN *start)
{
TOKEN *p;
for(p = start; p; p = p->next) {
}
}
// -- CombinePrepositionNoun --
// 連結を行わない例外
//
CMP_TOKEN pat_PrepNounRel[] = {
CMP_TOKEN( FR_PART_NOUN_ALL, JP_PROP_NONE, NULL),
CMP_TOKEN( FR_PART_RELATIVE_ALL, JP_PROP_NONE, NULL),
CMP_TOKEN( FR_PART_NONE)
};
// -- CombinePrepositionObject --
// 前置詞 + 名詞 → 前置詞句
// 例) dans une voiture
//
void
CombinePrepositionObject(TOKEN *start)
{
TOKEN *p = start;
TOKEN *lastPrep = NULL, *lastObj = NULL;
// 文末の前置詞は無視する
for(p = start; p; p = p->next) {
TOKEN *next = p->next;
if( (p->frPart & FR_PART_PREPOSIT)
&& !(p->frPart & FR_PART_COMBINE)
&& p->object1 == NULL
&& next
&& (next->frPartParent & FR_PART_PREPOSIT)
&& MatchPrepositionObject(p, next)) {
if(!IsPatternMatch(pat_PrepNounRel, next)) {
lastPrep = p;
lastObj = p->next;
}
} else if(ToWaitCombinePrepositionObject(p, lastPrep, lastObj)) {
lastPrep = lastObj = NULL;
}
}
if(lastPrep) {
CombinePrepositionObject(start, lastPrep, lastObj);
}
}
//
// Combine Preposition Objectを待つべきか?
//
BOOL
ToWaitCombinePrepositionObject(TOKEN *p, TOKEN *prep, TOKEN *obj)
{
if((p->frPart & FR_PART_SPECIAL)
&& p->frPart != FR_PART_SPECIAL_COMMA) {
// 目的語の名詞の後ろに関係代名詞が続いているかもしれない。
// Nous courons vers la baraque qui se trouvait dans la bois.
return(TRUE);
}
if( obj
&& p != obj
// S+V si S+V <, mais> S+V はOK
&& ((p->frPart & FR_PART_COMBINE) && (p->punctuation != FR_PUNCT_COMMA))
&& !(p->frPart & FR_PART_PREPOSIT)
&& p->object1 == NULL
&& ((p->frPart & FR_PART_ALL) & obj->frPart)
&& ((p->frPart & ~FR_PART_ALL) & obj->frPart)) {
// Avec du beuere ou de la confiture. バターかジャムを付けて
return(TRUE);
}
if(p->frPart & FR_PART_VERB) {
// すでに、前置詞の目的語となっている
if(obj == p) return(FALSE);
// De une main <tremblante>など
if(p->frTense == FR_TENSE_PASSIVE
|| p->frTense == FR_TENSE_P_PAST
|| p->frTense == FR_TENSE_P_PRESENT)
return(TRUE);
}
if(obj
&& obj->next
&& (obj->next->frPart & FR_PART_PREPOSIT)
&& (obj->next->frPartParent & obj->frPart)
&& MatchParentPreposition(obj, obj->next))
return(TRUE);
if((p->frPart & FR_PART_PREPOSIT)
&& !(p->frPart & FR_PART_COMBINE)
&& p->object1 == NULL)
return(TRUE);
return(FALSE);
}
JP_ADVERB dic_jpEnRetard("遅れ", JP_KIND_TA, JP_PROP_TIME, JP_PROP_ALL);
ADVERB dic_EnRetard = { "EN_RETARD", JPADVERB_DIC(&dic_jpEnRetard) };
void
CombinePrepositionObject(TOKEN *start, TOKEN *prep, TOKEN *obj)
{
TOKEN *q;
if((obj->frPartParent & FR_PART_VERB)
&& obj->next
&& obj->next->subject == NULL
&& (obj->next->frPart & FR_PART_VERB)) {
// <Comme je> vous le dis -> Comme <je vous le dis>
TOKEN *altP = CopyCurrentTree(obj, "CombinePrepositionObject");
altP->frPartParent = FR_PART_VERB;
}
for(q = start; q; q = q->next)
if(q == obj) break;
if(q) DisconnectTOKEN(start, obj);
if(IsObjectMatch(obj, FR_PART_NOUN_GENERAL, JP_PROP_NONE, NULL, "retard")) {
ChangeToAdverb(prep, &dic_EnRetard);
} else {
prep->object1 = obj;
SelectJpPreposition1(prep, obj);
// seulement aux gens. その少年達<だけ>に
obj->jpEmphasis |= prep->jpEmphasis;
// jusqu'<au> moment de parvenir.
if((obj->frPart & FR_PART_PREPOSIT)
|| IsObjectMatch(obj, FR_PART_SENTENCE_QUE))
SetPrtControlReplace(obj);
}
if(IsObjectMatch(obj, FR_PART_VERB_INF)) {
// 動詞を目的語としてとる前置詞は、frPartを特別に代える
if(prep->frPart == FR_PART_PREPOSIT_A) prep->frPart = FR_PART_PREPOSIT_A_INF;
if(prep->frPart == FR_PART_PREPOSIT_DE) prep->frPart = FR_PART_PREPOSIT_DE_INF;
if(prep->frPart == FR_PART_PREPOSIT_POUR) prep->frPart = FR_PART_PREPOSIT_POUR_INF;
}
}
// -- CombineParentPreposition1 --
// 名詞 + 前置詞句 → 名詞句
// Parentの辞書をたよりに連結する
// (主に熟語)
//
void
CombineParentPreposition1(TOKEN *start)
{
TOKEN *p;
TOKEN *noun = NULL, *adjective = NULL;
// 文末の前置詞は無視する
for(p = start; p; p = p->next) {
TOKEN *next = p->next;
if(!(p->frPart & FR_PART_COMBINE)
&& next
&& next->frPartChoice != FR_PART_OBJECT
&& ( IsObjectMatch(next, FR_PART_PREPOSIT_ALL)
|| IsObjectMatch(next, FR_PART_SENTENCE_QUE))) {
if(MatchNounObject(p, next)) {
noun = p; adjective = NULL;
p = next;
} else if(MatchAdjectiveObject(p, next)) {
noun = NULL; adjective = p;
p = next;
}
}
if((noun || adjective)
&& ToWaitCombineParentPreposition1(start, p)) {
noun = adjective = NULL;
}
}
if(noun) {
CombineNounObject(start, noun, noun->next);
} else if(adjective) {
CombineAdjectiveObject(start, adjective, adjective->next);
}
}
BOOL
ToWaitCombineParentPreposition1(TOKEN *start, TOKEN *p)
{
// favorable (@ la libert{<,> aux arts et aux lettres).
if(p->frPart == FR_PART_SPECIAL
&& (p->frPartChoice & FR_PART_COMBINE)
&& (p->frPartChoice & FR_PART_PREPOSIT))
return(TRUE);
if((p->frPart & FR_PART_COMBINE)
&& (p->frPart & FR_PART_PREPOSIT)
&& (p->object1 == NULL || p->object2 == NULL))
return(TRUE);
if((p->frPart & FR_PART_SPECIAL)
&& p->frPart != FR_PART_SPECIAL_COMMA)
return(TRUE);
if(IsObjectMatch(p, FR_PART_VERB_UNCLEAR)
&& !(p->frPart & FR_PART_COMBINE))
return(TRUE);
return(FALSE);
}
//
// -- CombineVerbPreposition --
// 動詞 + 前置詞句 → 動詞句
// 動詞辞書内の前置訳を優先するので、whichが決定した動詞のみ扱う
//
// S + V1 + V2 + prep -> S + (V1 + (V2 + prep))
// とするため、CombineVerbObjectより前に実行する
//
void
CombineVerbPreposition(TOKEN *start)
{
TOKEN *p;
TOKEN *lastParent = NULL, *lastPreposition = NULL;
for(p = start; p; p = p->next) {
if((p->frPart & FR_PART_VERB)
// 動詞訳に前置詞が含まれているかもしれない
&& p->which
// 間に関係代名詞は入れない
&& SearchToken(FR_PART_RELATIVE_ALL, p->child) == NULL
// && HasVerbVerbObject(p) == FALSE
&& p->next
&& (p->next->frPart & FR_PART_PREPOSIT)
&& p->next->frPartChoice != FR_PART_OBJECT
&& p->next->object1
&& (p->frPart & p->next->frPartParent)
&& MatchParentPreposition(p, p->next)) {
lastParent = p; lastPreposition = p->next;
}
}
if(lastParent
&& lastPreposition) {
CombineParentPreposition(start, lastParent, lastPreposition);
}
}
// Il se coupe par megarde le petit doigt.
// -> Il coupe <se> par megarde le petit dogit.
// coupeとparを注目できるように
CMP_TOKEN pat_VerbRecursivePreposition[] = {
CMP_TOKEN( FR_PART_VERB_UNCLEAR, JP_PROP_NONE, NULL),
CMP_TOKEN( FR_PART_NOUN_OBJECT_BOTH, JP_PROP_NONE, IsMoved),
CMP_TOKEN( FR_PART_PREPOSIT_ALL, JP_PROP_NONE, HasObject1),
CMP_TOKEN( FR_PART_NONE)
};
//
// -- CombineParentPreposition2 --
// 名詞 + 前置詞句 → 名詞句
// 前置詞の辞書をたよりに連結する
// (熟語を除く)
//
void
CombineParentPreposition2(TOKEN *start)
{
TOKEN *p;
TOKEN *lastParent = NULL, *lastPreposition = NULL;
// 文末の前置詞は無視する
for(p = start; p; p = p->next) {
if(IsPatternMatch(pat_VerbRecursivePreposition, p)
&& MatchVerbObject(p, p->next, p->next->next) == NULL) {
lastParent = p;
p = lastPreposition = SkipTokens(p, 2);
} else if(!(p->frPart & FR_PART_COMBINE)
// 動詞訳に前置詞が含まれているかもしれない
// 前置詞側からアプローチはしない
&& !IsObjectMatch(p, FR_PART_VERB_UNCLEAR)
// 間に関係代名詞は入れない
&& SearchToken(FR_PART_RELATIVE_ALL, p->child) == NULL
&& HasVerbVerbObject(p) == FALSE
// j'l ai pour -> je ai <le + pour> とならないように
&& p->moved == 0
&& p->next
&& (p->next->frPart & FR_PART_PREPOSIT)
&& p->next->frPartChoice != FR_PART_OBJECT
&& p->next->object1
&& (p->frPart & p->next->frPartParent)
&& MatchParentPreposition(p, p->next)) {
if(SearchToken(FR_PART_PREPOSIT_ALL, FR_PUNCT_COMMA, p->child)
&& p->punctuation != FR_PUNCT_COMMA)
break;
lastParent = p; lastPreposition = p->next;
}
}
if(lastParent
&& lastPreposition) {
CombineParentPreposition(start, lastParent, lastPreposition);
}
}
void
CombineParentPreposition(TOKEN *start, TOKEN *parent, TOKEN *prep)
{
if(!(prep->frPartParent & parent->frPart)
|| prep->frPartChoice == FR_PART_OBJECT)
return;
if(prep->frPartChoice & FR_PART_OBJECT)
ConsiderVerbObjectPreposition(start, parent, prep);
TOKEN *q; // 別の親になる可能性のあるToken
FR_PART frPart = (FR_PART)(prep->frPartParent & ~parent->frPart);
frPart = (FR_PART)(frPart & FR_PART_ALL);
frPart = (FR_PART)(frPart & ~FR_PART_ADVERB_ADJECTIVE);
for(q = start; q && q != parent && frPart; ) {
q = SearchPrepositionParent(q, parent, frPart);
if(q
&& (q->frPart & frPart)
&& MatchParentPreposition(q, prep)) {
// PrintInternalError( "ParentPreposition 2 : %s (%08x)\n", GetTokenFrench(prep), frPart);
TOKEN *altParent = CopyCurrentTree(q, "ParentPreposition 2");
TOKEN *altPrep = SkipTokens(altParent, TokenLength(q, prep));
altPrep->frPartParent = (FR_PART)(q->frPart & frPart);
altPrep->frPartChoice = FR_PART_PREPOSIT;
frPart = (FR_PART)(frPart & ~q->frPart);
CancelMiddlePreposition(altParent, altPrep);
// break;
}
if(q) q = q->next;
}
AttatchParentPreposition(start, parent, prep);
}
void
ConsiderVerbObjectPreposition(TOKEN *start, TOKEN *parent, TOKEN *prep)
{
TOKEN *verb;
for(verb = start; verb; verb = verb->next) {
// Prepositionを目的語としてとりそうな動詞を探す
verb = SearchToken(FR_PART_VERB_UNCLEAR, verb, parent);
if(verb == NULL) break;
if(HasPrepositionObject(verb, prep)) {
TOKEN *altP = CopyCurrentTree(prep, "ParentPreposition 3");
altP->frPartParent = FR_PART_NONE;
altP->frPartChoice = FR_PART_OBJECT; // 動詞の目的語専用
prep->frPartChoice = (FR_PART)(prep->frPartChoice & ~FR_PART_OBJECT);
return;
}
}
}
TOKEN
*SearchPrepositionParent(TOKEN *start, TOKEN *end, FR_PART frPart)
{
TOKEN *p;
for(p = start; p && p != end; p = p->next) {
if(p->frPart & frPart) return p;
// 間に関係代名詞は入らない
if(p->frPart & FR_PART_RELATIVE) break;
}
return(NULL);
}
//
// ParentとPrepsitionの間にある、Prepositionは、Parentに付けない
//
void
CancelMiddlePreposition(TOKEN *parent, TOKEN *prep)
{
TOKEN *p;
for(p = parent; p; p = p->next) {
p = SearchToken(prep->frPart, p, prep);
if(p == NULL) break;
// Verb + Prep1 + Prep2で、
// Verb + Prep2を連結したら、 Verb + Prep1は連結させない
p->frPartParent = (FR_PART)(p->frPartParent & ~parent->frPart);
}
}
void
AttatchParentPreposition(TOKEN *start, TOKEN *parent, TOKEN *prep)
{
TOKEN *q;
for(q = start; q; q = q->next) {
if(q == prep) break;
}
if(q) DisconnectTOKEN(start, prep);
if(SearchToken(prep->frPart, parent->child))
prep->scoreCombine += SCORE_SAME_CHILD;
prep->frPartParent = parent->frPart;
AddChildTOKEN(parent, prep);
if(prep->frPart != FR_PART_PREPOSIT_DE) {
if(parent->frPart & FR_PART_VERB)
prep->scoreCombine += SCORE_VERB_PREPOSITION;
}
SelectJpPreposition2(parent, prep);
if((parent->frPart & FR_PART_VERB)
&& parent->which
&& parent->object1 == NULL
&& parent->object2 == NULL
&& !IsAlwaysIntransitiveVerb(parent)) {
// 前置詞を処理したら、別の展開があるかもしれない
// eg) Il ne reste (@ cet {gard)(pour Marie) que des souvenirs tr}s amers.
prep->scoreCombine += SCORE_INSERTED_PREPOSITION;
parent->which = NULL;
// 本当は、object1, object2も返すべき?
// if(parent->object1) {
// InseartToken(parent, object1);
// parent->object1 = NULL;
// } なんてね。
}
if((parent->frPart & FR_PART_NOUN)
&& parent->punctuation == FR_PUNCT_COMMA
&& SearchToken(FR_PART_RELATIVE_ALL, parent->child) == NULL
&& SearchToken(FR_PART_PREPOSIT_ALL, parent->child, prep) == NULL) {
// 途中に挿入文があった場合、弱いよな
// eg) J'ai cri{ vers vous, Seigneur, <du> fond. 奥のあなた -> 奥からあなたを叫びました。
prep->scoreCombine = SCORE_SPILIT_PREPOSITION;
}
// 文章に連結する場合
if(parent->subject) {
prep->jpEmphasis |= JP_EMPHASIS_COMMA;
}
}
JP_PREPOSITION
*MatchPrepositionObject(TOKEN *p, TOKEN *object)
{
if((p->frPart & FR_PART_COMBINE)
|| IsObjectMatch(object, FR_PART_VERB_UNCLEAR))
return(NULL);
JP_PREPOSITION *jpPreposition = ((PREPOSITION *)p->what)->jpPreposition;
int proposed = ((PREPOSITION *)p->what)->proposed;
while(proposed-- > 0) {
if(IsObjectMatch(object, jpPreposition->object)) {
return(jpPreposition);
}
jpPreposition++;
}
return(NULL);
}
BOOL
SelectJpPreposition1(TOKEN *p, TOKEN *object)
{
if(p->frPart & FR_PART_COMBINE) return(FALSE);
JP_PREPOSITION *jpPreposition = MatchPrepositionObject(p, object);
if(jpPreposition) {
p->jpProp = jpPreposition->myJpProp;
if(p->jpProp == JP_PROP_NONE)
p->jpProp = object->jpProp;
p->which = jpPreposition;
return(TRUE);
} else
return(FALSE);
}
JP_PREPOSITION
*MatchParentPreposition(TOKEN *parent, TOKEN *prep)
{
if(parent == NULL
|| prep == NULL
|| prep->object1 == NULL
|| prep->frPartChoice == FR_PART_OBJECT // 動詞の目的語用に持っておいたもの
|| parent->frPart == FR_PART_NOUN_SUBJECT) // je, tu, ilに前置詞は付かない
return NULL;
if(prep->frPart & FR_PART_COMBINE) {
if(prep->object1 == NULL
|| prep->object2 == NULL)
return(NULL);
JP_PREPOSITION *ret1 = MatchParentPreposition(parent, prep->object1);
JP_PREPOSITION *ret2 = MatchParentPreposition(parent, prep->object2);
if(ret1 && ret2)
return(ret2); // てきとー
return(NULL);
}
// 補語人称代名詞は、前置詞を伴わない
if((parent->frPart & FR_PART_NOUN) && parent->moved)
return NULL;
TOKEN *object = prep->object1;
JP_PREPOSITION *jpPreposition = ((PREPOSITION *)prep->what)->jpPreposition;
int proposed = ((PREPOSITION *)prep->what)->proposed;
while(proposed-- > 0) {
if(IsObjectMatch(object, jpPreposition->object)
&& IsObjectMatch(parent, jpPreposition->parent)) {
return(jpPreposition);
}
jpPreposition++;
}
return(NULL);
}
BOOL
SelectJpPreposition2(TOKEN *parent, TOKEN *p)
{
if(p == NULL) return(FALSE);
if(p->frPart & FR_PART_COMBINE) {
BOOL ret1 = SelectJpPreposition2(parent, p->object1);
BOOL ret2 = SelectJpPreposition2(parent, p->object1);
if(ret1 && ret2) return(TRUE);
return(FALSE);
}
JP_PREPOSITION *jpPreposition = MatchParentPreposition(parent, p);
if(jpPreposition) {
p->jpProp = jpPreposition->myJpProp;
if(p->jpProp == JP_PROP_NONE) // 前置詞にpropがなければ目的語のpropを持ってくる
p->jpProp = p->object1->jpProp;
p->which = jpPreposition;
if(p->object1->frPart & FR_PART_NOUN)
SelectJpNoun(p, p->object1, p, jpPreposition->object.jpProp, JP_PROP_ALL);
if(jpPreposition->Exec)
jpPreposition->Exec(parent, p);
return(TRUE);
}
return(FALSE);
}